package com.xhwl.centiotdata.handler.device.impl;

import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.handler.device.DeviceIntegrationFactory;
import com.xhwl.centiotdata.handler.device.DeviceIntegrationHandler;
import com.xhwl.centiotdata.pojo.dto.alarmhost.DeviceGuangTuoAlarmHostDTO;
import com.xhwl.centiotdata.pojo.dto.alarmhost.DeviceStatusGuangTuoAlarmHostDTO;
import com.xhwl.centiotdata.pojo.dto.alarmhost.DeviceSubSystemStatusGuangTuoAlarmHostDTO;
import com.xhwl.centiotdata.pojo.dto.device.DeviceIntegrationConfigDTO;
import com.xhwl.centiotdata.service.cent.IDeviceCentService;
import com.xhwl.centiotdata.suppliersystem.guangtuo.DeviceGuangTuoAlarmHostHandler;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.enums.ProductEnum;
import com.xhwl.common.enums.device.DeviceOnlineStatusEnum;
import com.xhwl.common.pojo.ResultJson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhouyongzhou
 * @date 2023/04/20  16:32
 */
@Slf4j
@Service
public class DeviceIntegrationGuangTuoHandler extends DeviceIntegrationHandler {
    @Resource
    private DeviceGuangTuoAlarmHostHandler deviceGuangTuoAlarmHostHandler;

    @Resource
    private IDeviceCentService deviceCentService;

    private static final String ONOFFLINE_S = "onoffline_s";


    @Override
    public void afterPropertiesSet() throws Exception {
        DeviceIntegrationFactory.register(ProductEnum.GUANGTUO_ALARM_HOST.getId(), this);
    }

    @Override
    public void pullDevice(DeviceIntegrationConfigDTO configDTO) {
        if (configDTO.getDeviceType() == null) {
            log.error("projectId：{} pullDevice failed! deviceType is null!", configDTO.getProjectId());
            return;
        }
        if (configDTO.getIpAndPort() == null) {
            log.error("projectId：{} pullDevice failed! ipAndPort is null!", configDTO.getProjectId());
            return;
        }
        //拉取设备数据
        List<DeviceGuangTuoAlarmHostDTO> deviceGuangTuoAlarmHostDTO = deviceGuangTuoAlarmHostHandler.pullDeviceList(configDTO);
        if (CollectionUtils.isEmpty(deviceGuangTuoAlarmHostDTO)) {
            return;
        }
        //拉取设备状态数据
        List<DeviceStatusGuangTuoAlarmHostDTO> deviceStatusGuangTuoAlarmHostDTOList = deviceGuangTuoAlarmHostHandler.pullDeviceStatusList(configDTO);
        if (CollectionUtils.isEmpty(deviceStatusGuangTuoAlarmHostDTOList)) {
            return;
        }
        //拉取设备子系统状态数据
        List<DeviceSubSystemStatusGuangTuoAlarmHostDTO> deviceSubSystemStatusGuangTuoAlarmHostDTOList = deviceGuangTuoAlarmHostHandler.pullDeviceSubSystemStatusList(configDTO);
        if (CollectionUtils.isEmpty(deviceSubSystemStatusGuangTuoAlarmHostDTOList)) {
            deviceSubSystemStatusGuangTuoAlarmHostDTOList = new ArrayList<>();
        }
        //转换数据
        List<DeviceDTO> deviceDTOList =handleDevice(configDTO, deviceGuangTuoAlarmHostDTO, deviceStatusGuangTuoAlarmHostDTOList, deviceSubSystemStatusGuangTuoAlarmHostDTOList);
        //存储业务中台
        ResultJson resultJson = deviceCentService.asyncUpdateDevice(deviceDTOList);
        log.info("拉取广拓报警主机设备状态成功：{}", JSONObject.toJSONString(resultJson));
    }

    public static  List<DeviceDTO> handleDevice(DeviceIntegrationConfigDTO configDTO, List<DeviceGuangTuoAlarmHostDTO> deviceGuangTuoAlarmHostDTOList,
                                         List<DeviceStatusGuangTuoAlarmHostDTO> deviceStatusGuangTuoAlarmHostDTOList,
                                         List<DeviceSubSystemStatusGuangTuoAlarmHostDTO> deviceSubSystemStatusGuangTuoAlarmHostDTOList) {
        //TODO 目前厂家没有设备编码数据，目前只能模拟一台设备
        DeviceDTO deviceDTO = new DeviceDTO();
        deviceDTO.setProjectId(configDTO.getProjectId());
        deviceDTO.setProductId(configDTO.getProductId());
        deviceDTO.setCategoryId(configDTO.getCategoryEnum().getId());
        deviceDTO.setDeviceTypeId(configDTO.getDeviceType());
        deviceDTO.setThirdDeviceId("alarm-host-code-1");
        deviceDTO.setName(StringUtils.isNotBlank(deviceDTO.getName()) ? deviceDTO.getName() : "---");
        JSONObject attributeJson=new JSONObject();
        Integer[] onlineStatusArr = {DeviceOnlineStatusEnum.OFFLINE.getId()};
        List<Map> alarmHostList= deviceGuangTuoAlarmHostDTOList.stream().filter(item -> "input".equals(item.getUsedType())).map(device -> {
            Map<String, Object> deviceStatusMap = new HashMap<>(8);
            deviceStatusGuangTuoAlarmHostDTOList.forEach(deviceStatus -> {
                if (device.getObjID().equals(deviceStatus.getObjID())) {
                    String statusValue = deviceStatus.getStatusValue().toUpperCase(Locale.ROOT);
                    if (ONOFFLINE_S.equals(deviceStatus.getStatusType())) {
                        onlineStatusArr[0] = DeviceOnlineStatusEnum.ONLINE.getCode().equals(statusValue) ? DeviceOnlineStatusEnum.ONLINE.getId() : DeviceOnlineStatusEnum.OFFLINE.getId();
                    }
                    deviceStatusMap.put(deviceStatus.getStatusType(), deviceStatus.getStatusValue());
                }
            });
            deviceSubSystemStatusGuangTuoAlarmHostDTOList.forEach(subSystemStatus -> {
                if (device.getBelongSubSysNo().equals(subSystemStatus.getSubSystemNo())) {
                    deviceStatusMap.put("subSystemStatusValue", subSystemStatus.getSubSystemStatusValue());
                }
            });
            deviceDTO.setOnlineStatus(onlineStatusArr[0]);
            deviceStatusMap.put("objID", String.valueOf(device.getObjID()));
            deviceStatusMap.put("objNo", device.getObjNo());
            deviceStatusMap.put("belongSubSysNo", device.getBelongSubSysNo());
            deviceStatusMap.put("defAreaType", device.getDefAreaType());
            deviceStatusMap.put("usedType", device.getUsedType());
            return deviceStatusMap;
        }).collect(Collectors.toList());
        attributeJson.put("data",alarmHostList);
        deviceDTO.setAttributeJson(attributeJson);
        return Arrays.asList(deviceDTO);
    }
}
